# -*- coding: utf-8 -*-
"""
    moe.answers.handlers
    ~~~~~~~~~~~~~~~~~~~~

    Q&A handlers.

    :copyright: 2009 by tipfy.org.
    :license: BSD, see LICENSE.txt for more details.
"""
from werkzeug import cached_property

from tipfy import Response
from tipfy.appengine.db import get_entity_dict, populate_entity
from tipfy.auth import user_required
from tipfy.i18n import _, lazy_gettext
from tipfy.utils import slugify

from moe.handlers import BaseHandler
from moe.answers.forms import QuestionForm
from moe.answers.models import Question, question_pager_by_newest


class AnswersHandler(BaseHandler):
    """Base class for the Q&A app."""
    def __init__(self, app, request):
        BaseHandler.__init__(self, app, request)

        # Set a flag in context for menus.
        self.context['current_app'] = 'moe.answers'

        self.breadcrumbs.add(lazy_gettext('Home'), 'home/index')
        self.breadcrumbs.add(lazy_gettext('Answers'), 'answers/index')


class QuestionEntityMixin(object):
    @cached_property
    def question_entity(self):
        """If the id is set in the URL rule, it means the entity is required:
        a NotFound exception will be raised if it doesn't exist.
        """
        entity_id = self.request.rule_args.get('question_id')
        if entity_id is not None:
            entity = Question.get_by_id(entity_id)
            if not entity:
                self.abort(404)

            return entity

    @cached_property
    def form(self):
        return QuestionForm(self.request, obj=self.question_entity)


class QuestionListHandler(AnswersHandler):
    def get(self, **kwargs):
        entities, query_cursor = question_pager_by_newest()

        context = {
            'questions': entities,
            'cursor':    query_cursor,
        }
        return self.render_response('answers/question_list.html', **context)


class QuestionViewHandler(AnswersHandler, QuestionEntityMixin):
    def get(self, **kwargs):
        self.breadcrumbs.add(self.question_entity.latest_revision.title,
            'answers/view', question_id=self.question_entity.key().id(),
            slug=self.question_entity.slug)

        context = {
            'question': self.question_entity,
        }
        return self.render_response('answers/question_view.html', **context)


class QuestionEditHandler(AnswersHandler, QuestionEntityMixin):
    @user_required
    def get(self, **kwargs):
        if self.question_entity:
            self.breadcrumbs.add(_('Edit Question'), 'answers/edit',
                answer_id=self.question_entity.key().id())
        else:
            self.breadcrumbs.add(_('New Question'), 'answers/new')

        context = {
            'question': self.question_entity,
            'form':     self.form,
        }
        return self.render_response('answers/question_edit.html', **context)

    @user_required
    def post(self, **kwargs):
        success_msg = _('The question was saved.')

        if self.form.validate_with_messages(self.add_message, success_msg):
            editor_key = self.auth.user.key()
            slug = slugify(self.form.title.data, 45, 'question')

            question_values = {
                'author_key': editor_key,
                'tags':       self.form.tags.data,
                'slug':       slug,
            }
            revision_values = {
                'editor_key': editor_key,
                'editor_ip':  self.request.remote_addr,
                'title':      self.form.title.data,
                'body_raw':   self.form.body_raw.data,
                # XXX parse with creole
                'body':       self.form.body_raw.data,
                'tags':       self.form.tags.data,
            }

            res = Question.insert_or_update(self.question_entity,
                question_values, revision_values)
            if res:
                question_key = res[0]
                return self.redirect_to('answers/view',
                    question_id=question_key.id(), slug=slug)

        return self.get(**kwargs)
